﻿using System;
using Microsoft.Practices.SharePoint.Common.Logging;
using Smart.Common.Forms;
using Smart.Common.Locator;
using Smart.Common.Notifications;
using Smart.Common.Router;
using Smart.Common.Rules;
using Smart.Common.Security;
using Smart.Common.Templates;

namespace Smart.Common
{
	public class SPServicesInstance
	{
		public Guid SiteId { get; set; }

		/// <summary>
		/// Main configuration service
		/// </summary>
		public readonly IConfiguration Configuration;

		/// <summary>
		/// Main service locator
		/// </summary>
		public readonly IServiceLocator ServiceLocator;

		private ILogger _logger;

		/// <summary>
		/// SharePoint logger (Trace write to ULS, Log write to EventLog)
		/// </summary>
		public ILogger Logger
		{
			get { return _logger ?? (_logger = new SharePointLogger()); }
		}

		/// <summary>
		/// Add-on manager
		/// </summary>
		public readonly IAddonManager AddonManager;

		/// <summary>
		/// Event manager
		/// </summary>
		public readonly IEventManager EventManager;

		/// <summary>
		/// Template factory
		/// </summary>
		public readonly ITemplateFactory TemplateFactory;

		/// <summary>
		/// Rules factory
		/// </summary>
		public readonly IRulesFactory RulesFactory;

		/// <summary>
		/// Forms factory
		/// </summary>
		public readonly IFormsFactory FormsFactory;

		/// <summary>
		/// Security factory
		/// </summary>
		public readonly ISecurityFactory SecurityFactory;

		/// <summary>
		/// Router factory
		/// </summary>
		public readonly IRouterFactory RouterFactory;

		/// <summary>
		/// Notifications scope, WARNING! Shoud be disposed!
		/// </summary>
		public INotificationScope Notifications
		{
			get { return GetScope<INotificationScope>(Const.ScopeNames.Notifications); }
		}

		public SPServicesInstance(Guid siteId)
		{
			SiteId = siteId;

			Configuration = new Configuration(this);
			ServiceLocator = new ServiceLocator(this);
			AddonManager = new AddonManager(this);
			EventManager = new EventManager(this);
			TemplateFactory = new TemplateFactory(this);
			RulesFactory = new RulesFactory(this);
			FormsFactory = new FormsFactory(this);
			SecurityFactory = new SecurityFactory(this);
			RouterFactory = new RouterFactory(this);
		}

		public bool Loaded = false;

		/// <summary>
		/// Method to Load Services
		/// </summary>
		public void Load()
		{
			if (Loaded)
				return;

			Loaded = true;

			try
			{
				AddonManager.Load();
			}
			catch (Exception x)
			{
				H.LX("SPServicesInstance.AddonManager.Load", x);
			}
		}

		/// <summary>
		/// Creates scope context by <paramref name="scopeName"/>
		/// </summary>
		/// <typeparam name="TScopeType">Scope context type</typeparam>
		/// <param name="scopeName">Scope name</param>
		/// <returns>Scope context</returns>
		public TScopeType GetScope<TScopeType>(string scopeName)
			where TScopeType : class, IEntityScope
		{
			return EntityScope.GetScope<TScopeType>(this, scopeName);
		}

		/// <summary>
		/// Creates scope context by <paramref name="scopeName"/> with dynamic settings
		/// </summary>
		/// <typeparam name="TScopeType">Scope context Type</typeparam>
		/// <param name="scopeName">Scope name</param>
		/// <param name="scopeSettings">Scope settings</param>
		/// <returns>Scope context</returns>
		public TScopeType GetScope<TScopeType>(string scopeName, string[] scopeSettings)
			where TScopeType : class, IEntityScope
		{
			return EntityScope.GetScope<TScopeType>(this, scopeName, scopeSettings);
		}
	}
}